<!DOCTYPE html>
<html>

<head>
  <title>Quarkus - Quarkus Extension for Spring Web API</title>
  <script id="adobe_dtm" src="https://www.redhat.com/dtm.js" type="text/javascript"></script>
  <script src="/assets/javascript/highlight.pack.js" type="text/javascript"></script>
  <META HTTP-EQUIV='Content-Security-Policy' CONTENT="default-src 'none'; script-src 'self' 'unsafe-eval' 'sha256-ANpuoVzuSex6VhqpYgsG25OHWVA1I+F6aGU04LoI+5s=' 'sha256-ipy9P/3rZZW06mTLAR0EnXvxSNcnfSDPLDuh3kzbB1w=' js.bizographics.com https://www.redhat.com assets.adobedtm.com jsonip.com https://ajax.googleapis.com https://www.googletagmanager.com https://www.google-analytics.com https://use.fontawesome.com; style-src 'self' https://fonts.googleapis.com https://use.fontawesome.com; img-src 'self' *; media-src 'self' ; frame-src https://www.googletagmanager.com https://www.youtube.com; frame-ancestors 'none'; base-uri 'none'; object-src 'none'; form-action 'none'; font-src 'self' https://use.fontawesome.com https://fonts.gstatic.com;">
  <META HTTP-EQUIV='X-Frame-Options' CONTENT="DENY">
  <META HTTP-EQUIV='X-XSS-Protection' CONTENT="1; mode=block">
  <META HTTP-EQUIV='X-Content-Type-Options' CONTENT="nosniff">
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="description" content="Quarkus: Supersonic Subatomic Java">
  <meta name="twitter:card" content="summary_large_image">
  <meta name="twitter:site" content="@QuarkusIO"> 
  <meta name="twitter:creator" content="@QuarkusIO">
  <meta property="og:url" content="https://quarkus.io/guides/spring-web" />
  <meta property="og:title" content="Quarkus - Quarkus Extension for Spring Web API" />
  <meta property="og:description" content="Quarkus: Supersonic Subatomic Java" />
  <meta property="og:image" content="/assets/images/quarkus_card.png" />
  <link rel="canonical" href="https://quarkus.io/guides/spring-web">
  <link rel="shortcut icon" type="image/png" href="/favicon.ico" >
  <link rel="stylesheet" href="https://quarkus.io/guides/stylesheet/config.css" />
  <link rel="stylesheet" href="/assets/css/main.css" />
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous">
  <link rel="alternate" type="application/rss+xml"  href="https://quarkus.io/feed.xml" title="Quarkus">
  <script src="https://quarkus.io/assets/javascript/goan.js" type="text/javascript"></script>
  <script src="https://quarkus.io/assets/javascript/hl.js" type="text/javascript"></script>
</head>

<body class="guides">
  <!-- Google Tag Manager (noscript) -->
  <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-NJWS5L"
  height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->

  <div class="nav-wrapper">
  <div class="grid-wrapper">
    <div class="width-12-12">
      <input type="checkbox" id="checkbox" />
      <nav id="main-nav" class="main-nav">
  <div class="container">
    <div class="logo-wrapper">
      
        <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_600px_reverse.png" class="project-logo" title="Quarkus"></a>
      
    </div>
    <label class="nav-toggle" for="checkbox">
      <i class="fa fa-bars"></i>
    </label>
    <div id="menu" class="menu">
      <span>
        <a href="/get-started/" class="">Get Started</a>
      </span>
      <span>
        <a href="/guides/" class="active">Guides</a>
      </span>
      <span>
        <a href="/community/" class="">Community</a>
      </span>
      <span>
        <a href="/support/" class="">Support</a>
      </span>
      <span>
        <a href="/blog/" class="">Blog</a>
      </span>
      <span>
        <a href="https://code.quarkus.io" class="button-cta secondary white">Start Coding</a>
      </span>
    </div>
  </div>
      </nav>
    </div>
  </div>
</div>

  <div class="content">
    <div class="guide">
  <div class="width-12-12">
    <h1 class="text-caps">Quarkus - Quarkus Extension for Spring Web API</h1>
    <div class="hide-mobile toc"><ul class="sectlevel1">
<li><a href="#prerequisites">Prerequisites</a></li>
<li><a href="#solution">Solution</a></li>
<li><a href="#creating-the-maven-project">Creating the Maven project</a></li>
<li><a href="#greetingcontroller">GreetingController</a></li>
<li><a href="#greetingcontrollertest">GreetingControllerTest</a></li>
<li><a href="#package-and-run-the-application">Package and run the application</a></li>
<li><a href="#run-the-application-as-a-native-executable">Run the application as a native executable</a></li>
<li><a href="#going-further-with-an-endpoint-returning-json">Going further with an endpoint returning JSON</a></li>
<li><a href="#adding-openapi-and-swagger-ui">Adding OpenAPI and Swagger-UI</a>
<ul class="sectlevel2">
<li><a href="#adding-microprofile-openapi-annotations">Adding MicroProfile OpenAPI Annotations</a></li>
<li><a href="#using-swagger-ui">Using Swagger UI</a></li>
</ul>
</li>
<li><a href="#supported-spring-web-functionalities">Supported Spring Web functionalities</a>
<ul class="sectlevel2">
<li><a href="#annotations">Annotations</a></li>
<li><a href="#controller-method-return-types">Controller method return types</a></li>
<li><a href="#controller-method-parameter-types">Controller method parameter types</a></li>
<li><a href="#exception-handler-method-return-types">Exception handler method return types</a></li>
<li><a href="#exception-handler-method-parameter-types">Exception handler method parameter types</a></li>
</ul>
</li>
<li><a href="#important-technical-note">Important Technical Note</a></li>
<li><a href="#conversion-table">Conversion Table</a></li>
<li><a href="#more-spring-guides">More Spring guides</a></li>
</ul></div>
    <div>
      <div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>While users are encouraged to use JAX-RS annotation for defining REST endpoints, Quarkus provides a compatibility layer for Spring Web in the form of the <code>spring-web</code> extension.</p>
</div>
<div class="paragraph">
<p>This guide explains how a Quarkus application can leverage the well known Spring Web annotations to define RESTful services.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>This technology is considered preview.</p>
</div>
<div class="paragraph">
<p>In <em>preview</em>, backward compatibility and presence in the ecosystem is not guaranteed.
Specific improvements might require to change configuration or APIs and plans to become <em>stable</em> are under way.
Feedback is welcome on our <a href="https://groups.google.com/d/forum/quarkus-dev">mailing list</a> or as issues in our <a href="https://github.com/quarkusio/quarkus/issues">GitHub issue tracker</a>.</p>
</div>
<div class="paragraph">
<p>For a full list of possible extension statuses, check our <a href="https://quarkus.io/faq/#extension-status">FAQ entry</a>.</p>
</div>
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="prerequisites"><a class="anchor" href="#prerequisites"></a>Prerequisites</h2>
<div class="sectionbody">
<div class="paragraph">
<p>To complete this guide, you need:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>less than 15 minutes</p>
</li>
<li>
<p>an IDE</p>
</li>
<li>
<p>JDK 1.8+ installed with <code>JAVA_HOME</code> configured appropriately</p>
</li>
<li>
<p>Apache Maven 3.6.2+</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="solution"><a class="anchor" href="#solution"></a>Solution</h2>
<div class="sectionbody">
<div class="paragraph">
<p>We recommend that you follow the instructions in the next sections and create the application step by step.
However, you can go right to the completed example.</p>
</div>
<div class="paragraph">
<p>Clone the Git repository: <code>git clone <a href="https://github.com/quarkusio/quarkus-quickstarts.git" class="bare">https://github.com/quarkusio/quarkus-quickstarts.git</a></code>, or download an <a href="https://github.com/quarkusio/quarkus-quickstarts/archive/master.zip">archive</a>.</p>
</div>
<div class="paragraph">
<p>The solution is located in the <code>spring-web-quickstart</code> <a href="https://github.com/quarkusio/quarkus-quickstarts/tree/master/spring-web-quickstart">directory</a>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="creating-the-maven-project"><a class="anchor" href="#creating-the-maven-project"></a>Creating the Maven project</h2>
<div class="sectionbody">
<div class="paragraph">
<p>First, we need a new project. Create a new project with the following command:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">mvn io.quarkus:quarkus-maven-plugin:1.7.0.Final:create \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=spring-web-quickstart \
    -DclassName="org.acme.spring.web.GreetingController" \
    -Dpath="/greeting" \
    -Dextensions="spring-web"
cd spring-web-quickstart</code></pre>
</div>
</div>
<div class="paragraph">
<p>This command generates a Maven project with a REST endpoint and imports the <code>spring-web</code> extension.</p>
</div>
<div class="paragraph">
<p>If you already have your Quarkus project configured, you can add the <code>spring-web</code> extension
to your project by running the following command in your project base directory:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="bash" class="language-bash hljs">./mvnw quarkus:add-extension -Dextensions="spring-web"</code></pre>
</div>
</div>
<div class="paragraph">
<p>This will add the following to your <code>pom.xml</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="xml" class="language-xml hljs">&lt;dependency&gt;
    &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
    &lt;artifactId&gt;quarkus-spring-web&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="greetingcontroller"><a class="anchor" href="#greetingcontroller"></a>GreetingController</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The Quarkus maven plugin automatically generated a controller with the Spring Web annotations to define our REST endpoint (instead of the JAX-RS ones used by default)
The <code>src/main/java/org/acme/spring/web/GreetingController.java</code> file looks as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package org.acme.spring.web;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/greeting")
public class GreetingController {

    @GetMapping
    public String hello() {
        return "hello";
    }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="greetingcontrollertest"><a class="anchor" href="#greetingcontrollertest"></a>GreetingControllerTest</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Note that a test for the controller has been created as well:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package org.acme.spring.web;

import io.quarkus.test.junit.QuarkusTest;
import org.junit.jupiter.api.Test;

import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.is;

@QuarkusTest
public class GreetingControllerTest {

    @Test
    public void testHelloEndpoint() {
        given()
          .when().get("/greeting")
          .then()
             .statusCode(200)
             .body(is("hello"));
    }

}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="package-and-run-the-application"><a class="anchor" href="#package-and-run-the-application"></a>Package and run the application</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Run the application with: <code>./mvnw compile quarkus:dev</code>.
Open your browser to <a href="http://localhost:8080/greeting" class="bare">http://localhost:8080/greeting</a>.</p>
</div>
<div class="paragraph">
<p>The result should be: <code>{"message": "hello"}</code>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="run-the-application-as-a-native-executable"><a class="anchor" href="#run-the-application-as-a-native-executable"></a>Run the application as a native executable</h2>
<div class="sectionbody">
<div class="paragraph">
<p>You can of course create a native image using the instructions of the <a href="building-native-image">Building a native executable guide</a>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="going-further-with-an-endpoint-returning-json"><a class="anchor" href="#going-further-with-an-endpoint-returning-json"></a>Going further with an endpoint returning JSON</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>GreetingController</code> above was an example of a very simple endpoint. In many cases however it is required to return JSON content.
The following example illustrates how that could be achieved using a Spring RestController:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/greeting")
public class GreetingController {

    @GetMapping("/{name}")
    public Greeting hello(@PathVariable(name = "name") String name) {
        return new Greeting("hello " + name);
    }

    public static class Greeting {
        private final String message;

        public Greeting(String message) {
            this.message = message;
        }

        public String getMessage(){
            return message;
        }
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The corresponding test could look like:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package org.acme.spring.web;

import io.quarkus.test.junit.QuarkusTest;
import org.junit.jupiter.api.Test;

import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.is;

@QuarkusTest
public class GreetingControllerTest {

    @Test
    public void testHelloEndpoint() {
        given()
          .when().get("/greeting/quarkus")
          .then()
            .statusCode(200)
            .body("message", is("hello quarkus"));
    }

}</code></pre>
</div>
</div>
<div class="paragraph">
<p>It should be noted that when using the Spring Web support in Quarkus, <a href="https://github.com/FasterXML/jackson">Jackson</a> is automatically added to the classpath and properly setup.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="adding-openapi-and-swagger-ui"><a class="anchor" href="#adding-openapi-and-swagger-ui"></a>Adding OpenAPI and Swagger-UI</h2>
<div class="sectionbody">
<div class="paragraph">
<p>You can add support for <a href="https://www.openapis.org/">OpenAPI</a> and <a href="https://swagger.io/tools/swagger-ui/">Swagger-UI</a> by using the <code>quarkus-smallrye-openapi</code> extension.</p>
</div>
<div class="paragraph">
<p>Add the extension by running this command:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="bash" class="language-bash hljs">./mvnw quarkus:add-extension -Dextensions="io.quarkus:quarkus-smallrye-openapi"</code></pre>
</div>
</div>
<div class="paragraph">
<p>This will add the following to your <code>pom.xml</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="xml" class="language-xml hljs">&lt;dependency&gt;
    &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
    &lt;artifactId&gt;quarkus-smallrye-openapi&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>This is enough to generate a basic OpenAPI schema document from your REST Endpoints:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="bash" class="language-bash hljs">curl http://localhost:8080/openapi</code></pre>
</div>
</div>
<div class="paragraph">
<p>You will see the generated OpenAPI schema document:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="yaml" class="language-yaml hljs">---
openapi: 3.0.1
info:
  title: Generated API
  version: "1.0"
paths:
  /greeting:
    get:
      responses:
        "200":
          description: OK
          content:
            '*/*':
              schema:
                type: string
  /greeting/{name}:
    get:
      parameters:
      - name: name
        in: path
        required: true
        schema:
          type: string
      responses:
        "200":
          description: OK
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/Greeting'
components:
  schemas:
    Greeting:
      type: object
      properties:
        message:
          type: string</code></pre>
</div>
</div>
<div class="paragraph">
<p>Also see <a href="https://quarkus.io/guides/openapi-swaggerui">the OpenAPI Guide</a></p>
</div>
<div class="sect2">
<h3 id="adding-microprofile-openapi-annotations"><a class="anchor" href="#adding-microprofile-openapi-annotations"></a>Adding MicroProfile OpenAPI Annotations</h3>
<div class="paragraph">
<p>You can use <a href="https://github.com/eclipse/microprofile-open-api">MicroProfile OpenAPI</a> to better document your schema,
example, adding the following to the class level of the <code>GreetingController</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">@OpenAPIDefinition(
    info = @Info(
        title="Greeting API",
        version = "1.0.1",
        contact = @Contact(
            name = "Greeting API Support",
            url = "http://exampleurl.com/contact",
            email = "techsupport@example.com"),
        license = @License(
            name = "Apache 2.0",
            url = "http://www.apache.org/licenses/LICENSE-2.0.html"))
)</code></pre>
</div>
</div>
<div class="paragraph">
<p>And describe your endpoints like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">@Tag(name = "Hello", description = "Just say hello")
@GetMapping(produces=MediaType.TEXT_PLAIN_VALUE)
public String hello() {
    return "hello";
}

@GetMapping(value = "/{name}", produces=MediaType.APPLICATION_JSON_VALUE)
@Tag(name = "Hello to someone", description = "Just say hello to someone")
public Greeting hello(@PathVariable(name = "name") String name) {
    return new Greeting("hello " + name);
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>will generate this OpenAPI schema:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="yaml" class="language-yaml hljs">---
openapi: 3.0.1
info:
  title: Greeting API
  contact:
    name: Greeting API Support
    url: http://exampleurl.com/contact
    email: techsupport@example.com
  license:
    name: Apache 2.0
    url: http://www.apache.org/licenses/LICENSE-2.0.html
  version: 1.0.1
tags:
- name: Hello
  description: Just say hello
- name: Hello to someone
  description: Just say hello to someone
paths:
  /greeting:
    get:
      tags:
      - Hello
      responses:
        "200":
          description: OK
          content:
            '*/*':
              schema:
                type: string
  /greeting/{name}:
    get:
      tags:
      - Hello to someone
      parameters:
      - name: name
        in: path
        required: true
        schema:
          type: string
      responses:
        "200":
          description: OK
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/Greeting'
components:
  schemas:
    Greeting:
      type: object
      properties:
        message:
          type: string</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="using-swagger-ui"><a class="anchor" href="#using-swagger-ui"></a>Using Swagger UI</h3>
<div class="paragraph">
<p>Swagger UI is included by default when running in <code>Dev</code> or <code>Test</code> mode, and can optionally added to <code>Prod</code> mode.
See <a href="https://quarkus.io/guides/openapi-swaggerui#use-swagger-ui-for-development">the Swagger UI</a> Guide for more details.</p>
</div>
<div class="paragraph">
<p>Navigate to <a href="http://localhost:8080/swagger-ui/">localhost:8080/swagger-ui/</a> and you will see the Swagger UI screen:</p>
</div>
<div class="paragraph">
<p><span class="image"><img src="/guides/images/spring-web-guide-screenshot01.png" alt="Swagger UI"></span></p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="supported-spring-web-functionalities"><a class="anchor" href="#supported-spring-web-functionalities"></a>Supported Spring Web functionalities</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Quarkus currently supports a subset of the functionalities that Spring Web provides. More specifically Quarkus supports the REST related features of Spring Web
(think of <code>@RestController</code> instead of <code>@Controller</code>).</p>
</div>
<div class="sect2">
<h3 id="annotations"><a class="anchor" href="#annotations"></a>Annotations</h3>
<div class="paragraph">
<p>The table below summarizes the supported annotations:</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<caption class="title">Table 1. Supported Spring Web annotation</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Name</th>
<th class="tableblock halign-left valign-top">Comments</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">@RestController</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">@RequestMapping</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">@GetMapping</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">@PostMapping</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">@PutMapping</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">@DeleteMapping</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">@PatchMapping</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">@RequestParam</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">@RequestHeader</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">@MatrixVariable</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">@PathVariable</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">@CookieValue</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">@RequestBody</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">@ResponseStatus</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">@ExceptionHandler</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Can only be used in a @RestControllerAdvice class, not on a per-controller basis</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">@RestControllerAdvice</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Only the @ExceptionHandler capability is supported</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="controller-method-return-types"><a class="anchor" href="#controller-method-return-types"></a>Controller method return types</h3>
<div class="paragraph">
<p>The following method return types are supported:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Primitive types</p>
</li>
<li>
<p>String (which will be used as a literal, no Spring MVC view support is provided)</p>
</li>
<li>
<p>POJO classes which will be serialized via JSON</p>
</li>
<li>
<p><code>org.springframework.http.ResponseEntity</code></p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="controller-method-parameter-types"><a class="anchor" href="#controller-method-parameter-types"></a>Controller method parameter types</h3>
<div class="paragraph">
<p>In addition to the method parameters that can be annotated with the appropriate Spring Web annotations from the previous table,
<code>javax.servlet.http.HttpServletRequest</code> and <code>javax.servlet.http.HttpServletResponse</code> are also supported.
For this to function however, users need to add the <code>quarkus-undertow</code> dependency.</p>
</div>
</div>
<div class="sect2">
<h3 id="exception-handler-method-return-types"><a class="anchor" href="#exception-handler-method-return-types"></a>Exception handler method return types</h3>
<div class="paragraph">
<p>The following method return types are supported:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>org.springframework.http.ResponseEntity</code></p>
</li>
<li>
<p><code>java.util.Map</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Other return types mentioned in the Spring <code><a href="https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/bind/annotation/ExceptionHandler.html">ExceptionHandler javadoc</a></code> are not supported.</p>
</div>
</div>
<div class="sect2">
<h3 id="exception-handler-method-parameter-types"><a class="anchor" href="#exception-handler-method-parameter-types"></a>Exception handler method parameter types</h3>
<div class="paragraph">
<p>The following parameter types are supported, in arbitrary order:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>An exception argument: declared as a general <code>Exception</code> or as a more specific exception. This also serves as a mapping hint if the annotation itself does not narrow the exception types through its <code>value()</code>.</p>
</li>
<li>
<p>Request and/or response objects (typically from the Servlet API). You may choose any specific request/response type, e.g. <code>ServletRequest</code> / <code>HttpServletRequest</code>. To use Servlet API, the <code>quarkus-undertow</code> dependency needs to be added.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Other parameter types mentioned in the Spring <code><a href="https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/bind/annotation/ExceptionHandler.html">ExceptionHandler javadoc</a></code> are not supported.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="important-technical-note"><a class="anchor" href="#important-technical-note"></a>Important Technical Note</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Please note that the Spring support in Quarkus does not start a Spring Application Context nor are any Spring infrastructure classes run.
Spring classes and annotations are only used for reading metadata and / or are used as user code method return types or parameter types.
What that means for end users, is that adding arbitrary Spring libraries will not have any effect. Moreover Spring infrastructure
classes (like <code>org.springframework.beans.factory.config.BeanPostProcessor</code> for example) will not be executed.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="conversion-table"><a class="anchor" href="#conversion-table"></a>Conversion Table</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The following table shows how Spring Web annotations can be converted to JAX-RS annotations.</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 33.3333%;">
<col style="width: 33.3333%;">
<col style="width: 33.3334%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Spring</th>
<th class="tableblock halign-left valign-top">JAX-RS</th>
<th class="tableblock halign-left valign-top">Comments</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">@RequestController</p></td>
<td class="tableblock halign-left valign-top"></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">There is no equivalent in JAX-RS. Annotating a class with @Path suffices</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">@RequestMapping(path="/api")</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">@Path("/api")</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">@RequestMapping(consumes="application/json")</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">@Consumes("application/json")</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">@RequestMapping(produces="application/json")</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">@Produces("application/json")</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">@RequestParam</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">@QueryParam</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">@PathVariable</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">@PathParam</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">@RequestBody</p></td>
<td class="tableblock halign-left valign-top"></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">No equivalent in JAX-RS. Method parameters corresponding to the body of the request are handled in JAX-RS without requiring any annotation</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">@RestControllerAdvice</p></td>
<td class="tableblock halign-left valign-top"></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">No equivalent in JAX-RS</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">@ResponseStatus</p></td>
<td class="tableblock halign-left valign-top"></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">No equivalent in JAX-RS</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">@ExceptionHandler</p></td>
<td class="tableblock halign-left valign-top"></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">No equivalent annotation in JAX-RS. Exceptions are handled by implementing <code>javax.ws.rs.ext.ExceptionMapper</code></p></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect1">
<h2 id="more-spring-guides"><a class="anchor" href="#more-spring-guides"></a>More Spring guides</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Quarkus has more Spring compatibility features. See the following guides for more details:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><a href="spring-di">Quarkus - Extension for Spring DI</a></p>
</li>
<li>
<p><a href="spring-data-jpa">Quarkus - Extension for Spring Data JPA</a></p>
</li>
<li>
<p><a href="spring-security">Quarkus - Extension for Spring Security</a></p>
</li>
<li>
<p><a href="spring-cloud-config-client">Quarkus - Reading properties from Spring Cloud Config Server</a></p>
</li>
<li>
<p><a href="spring-boot-properties">Quarkus - Extension for Spring Boot properties</a></p>
</li>
<li>
<p><a href="spring-cache">Quarkus - Extension for Spring Cache</a></p>
</li>
<li>
<p><a href="spring-scheduled">Quarkus - Extension for Spring Scheduled</a></p>
</li>
</ul>
</div>
</div>
</div>
    </div>
  </div>
</div>

  </div>

  <div class="content project-footer">
  <div class="footer-section">
    <div class="logo-wrapper">
      <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_reverse.svg" class="project-logo" title="Quarkus"></a>
    </div>
  </div>
  <div class="grid-wrapper">
    <p class="grid__item width-3-12">Quarkus is open. All dependencies of this project are available under the <a href='https://www.apache.org/licenses/LICENSE-2.0' target='_blank'>Apache Software License 2.0</a> or compatible license.<br /><br />This website was built with <a href='https://jekyllrb.com/' target='_blank'>Jekyll</a>, is hosted on <a href='https://pages.github.com/' target='_blank'>Github Pages</a> and is completely open source. If you want to make it better, <a href='https://github.com/quarkusio/quarkusio.github.io' target='_blank'>fork the website</a> and show us what you’ve got.</p>

    
      <div class="width-1-12 project-links">
        <span>Navigation</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="/">Home</a></li>
          
            <li><a href="/guides">Guides</a></li>
          
            <li><a href="/community/#contributing">Contribute</a></li>
          
            <li><a href="/faq">FAQ</a></li>
          
            <li><a href="/get-started">Get Started</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Contribute</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://twitter.com/quarkusio">Follow us</a></li>
          
            <li><a href="https://github.com/quarkusio">GitHub</a></li>
          
            <li><a href="/security">Security&nbsp;policy</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Get Help</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://groups.google.com/forum/#!forum/quarkus-dev">Forums</a></li>
          
            <li><a href="https://quarkusio.zulipchat.com">Chatroom</a></li>
          
        </ul>
      </div>
    

    
      <div class="width-3-12 more-links">
        <span>Quarkus is made of community projects</span>
        <ul class="footer-links">
          
            <li><a href="https://vertx.io/" target="_blank">Eclipse Vert.x</a></li>
          
            <li><a href="https://microprofile.io" target="_blank">Eclipse MicroProfile</a></li>
          
            <li><a href="https://hibernate.org" target="_blank">Hibernate</a></li>
          
            <li><a href="https://netty.io" target="_blank">Netty</a></li>
          
            <li><a href="https://resteasy.github.io" target="_blank">RESTEasy</a></li>
          
            <li><a href="https://camel.apache.org" target="_blank">Apache Camel</a></li>
          
            <li><a href="https://code.quarkus.io/" target="_blank">And many more...</a></li>
          
        </ul>
      </div>
    
  </div>
</div>
  <div class="content redhat-footer">
  <div class="grid-wrapper">
    <span class="licence">
      <i class="fab fa-creative-commons"></i><i class="fab fa-creative-commons-by"></i> <a href="https://creativecommons.org/licenses/by/3.0/" target="_blank">CC by 3.0</a> | <a href="https://www.redhat.com/en/about/privacy-policy">Privacy Policy</a>
    </span>
    <span class="redhat">
      Sponsored by
    </span>
    <span class="redhat-logo">
      <a href="https://www.redhat.com/" target="_blank"><img src="/assets/images/redhat_reversed.svg"></a>
    </span>
  </div>
</div>


  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js" integrity="sha384-8gBf6Y4YYq7Jx97PIqmTwLPin4hxIzQw5aDmUg/DDhul9fFpbbLcLh3nTIIDJKhx" crossorigin="anonymous"></script>
  <script type="text/javascript" src="/assets/javascript/mobile-nav.js"></script>
  <script type="text/javascript" src="/assets/javascript/scroll-down.js"></script>
  <script src="/assets/javascript/satellite.js" type="text/javascript"></script>
  <script src="https://quarkus.io/guides/javascript/config.js" type="text/javascript"></script>
  <script src="/assets/javascript/search-filter.js" type="text/javascript"></script>
  <script src="/assets/javascript/back-to-top.js" type="text/javascript"></script>
</body>

</html>
